package com.education.platform.api.service.impl.common;

import com.alibaba.fastjson.JSON;
import com.education.platform.api.service.common.Validservice;
import com.education.platform.api.sms.AliyunSmsUtil;
import com.education.platform.api.sms.SmsConfiguration;
import com.education.platform.common.exception.BusinessException;
import com.education.platform.common.redis.RedisUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * 验证服务
 */
@Service
public class ValidServiceImpl implements Validservice {
    private Logger logger = LoggerFactory.getLogger(ValidServiceImpl.class);
    private static final String SMS_FORMAT = "SMS-%S-%S";
    /**
     * 过期时间
     */
    @Value("${captcha.sms.time.expire}")
    private int expireTime;
    /**
     * 有效时间
     */
    @Value("${captcha.sms.time.interval}")
    private int intervalTime;
    /**
     * 验证码长度
     */
    @Value("${captcha.sms.code.size}")
    private int defaultCodeSize;

    @Autowired
    private RedisUtils redisUtils;


    @Autowired
    SmsConfiguration smsConfiguration;

    private static String testCode="3787";
    private static String testPhone="13548005539";

    /**
     * 发送验证码
     * @param mobile 手机号码
     * @param type 类型
     * @return
     */
    @Override
    public void sendMessageCode(String mobile, Integer type) {
        String code = randomCode(defaultCodeSize);
        String key = String.format(SMS_FORMAT, mobile, type);
        //获取过期剩余时间
        Long m = redisUtils.ttl(key);
        if (m > (expireTime - intervalTime)) {
            throw new BusinessException(String.format("请间隔%s秒后再获取验证码", intervalTime));
        }
        redisUtils.setString(key, expireTime, code);
        logger.info(String.format("发送验证码：%s", code));
        Map map = new HashMap(1);
        map.put(smsConfiguration.getTemplateKey(),code);
        AliyunSmsUtil.sendSms(mobile, JSON.toJSONString(map),smsConfiguration);
    }


    /**
     * 校验验证码
     * @param mobile
     * @param code
     * @param type
     * @return
     */
    @Override
    public Boolean validMessageCode(String mobile, String code, Integer type) {
        // TODO: 2020/7/19  测试账号 验证码
        if(testCode.equals(code)&&testPhone.equals(mobile)){
            return true;
        }
        String key = String.format(SMS_FORMAT, mobile, type);
        String cacheCode = redisUtils.getString(key);
        if (cacheCode == null) {
            return false;
        } else if (!cacheCode.equals(code)) {
            return false;
        }
        redisUtils.del(key);
        return true;
    }

    @Override
    public void validMessageCodeThrowE(String mobile, String code, Integer type) {
        if (!validMessageCode(mobile, code, type)) {
            throw new BusinessException("验证码不正确");
        }
    }


    /**
     * 生成 n 位随机数
     * @param n
     * @return
     */
    public String randomCode(int n) {
        StringBuilder code = new StringBuilder(n);
        Random random = new Random();
        while (code.length() < n) {
            code.append(random.nextInt(10));
        }
        return code.toString();
    }
}
